package com.bailian.system.utils;

import java.math.BigDecimal;
import java.math.RoundingMode;import java.util.List;
import java.util.ArrayList;
import java.util.stream.Collectors;
import com.bailian.system.domain.*;
import com.bailian.system.mapper.*;
import com.bailian.system.domain.vo.BlParkVo;
import com.fasterxml.jackson.core.type.TypeReference;
import com.fasterxml.jackson.databind.ObjectMapper;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

/**
 * 园区VO转换工具类
 * 
 * @author bailian
 * @date 2025-08-04
 */
@Component
public class ParkVoConverter {
    
    private static final Logger log = LoggerFactory.getLogger(ParkVoConverter.class);
    private static final ObjectMapper objectMapper = new ObjectMapper();
    
    @Autowired
    private BlParkTagsMapper parkTagsMapper;
    
    @Autowired
    private BlWarehouseTypeMapper warehouseTypeMapper;
    
    @Autowired
    private BlParkConfigMapper parkConfigMapper;
    
    @Autowired
    private BlParkServiceMapper parkServiceMapper;

    @Autowired
    private BlParkMapper blParkMapper;
    
    /**
     * 将BlPark转换为BlParkVo
     * 
     * @param blPark 园区实体
     * @return 园区VO
     */
    public BlParkVo convertToVo(BlPark blPark) {
        if (blPark == null) {
            return null;
        }
        
        BlParkVo vo = new BlParkVo();
        
        // 复制基本属性
        vo.setParkId(blPark.getParkId());
        vo.setParkName(blPark.getParkName());
        vo.setParkDescription(blPark.getParkDescription());
        vo.setTotalArea(blPark.getTotalArea());
        vo.setBuildingArea(blPark.getBuildingArea());
        vo.setFloorHeight(blPark.getFloorHeight());
        vo.setLocation(blPark.getLocation());
        vo.setLongitude(blPark.getLongitude());
        vo.setLatitude(blPark.getLatitude());
        vo.setRentedArea(blPark.getRentedArea());
        vo.setRentalPrice(blPark.getRentalPrice());
        vo.setManager(blPark.getManager());
        vo.setContactPhone(blPark.getContactPhone());
        vo.setThumbnailUrl(blPark.getThumbnailUrl());
        vo.setPosterUrl(blPark.getPosterUrl());
        vo.setIsRecommend(blPark.getIsRecommend());
        vo.setCreateTime(blPark.getCreateTime());
        vo.setUpdateTime(blPark.getUpdateTime());
        vo.setAreaId(blPark.getAreaId());
        vo.setContactAddress(blPark.getContactAddress());
        vo.setContactEmail(blPark.getContactEmail());
        vo.setBannerPage(blPark.getBannerPage());
        vo.setFireLevel(blPark.getFireLevel());        
        // 初始化列表为[]，避免前端看到null
        vo.setParkTags(new ArrayList<>());
        vo.setWarehouseTypes(new ArrayList<>());
        vo.setHardwareConfig(new ArrayList<>());
        vo.setParkServices(new ArrayList<>());
        
        // 通过中间表关系补齐列表字段
        List<Long> tagIds = blParkMapper.selectParkTagIdsByParkId(blPark.getParkId());
        if (tagIds != null && !tagIds.isEmpty()) {
            List<BlParkTags> tags = new ArrayList<>();
            for (Long tagId : tagIds) {
                BlParkTags tag = parkTagsMapper.selectBlParkTagsByTagId(tagId);
                if (tag != null) tags.add(tag);
            }
            vo.setParkTags(tags);
        }

        List<Long> configIds = blParkMapper.selectParkConfigIdsByParkId(blPark.getParkId());
        if (configIds != null && !configIds.isEmpty()) {
            List<BlParkConfig> configs = new ArrayList<>();
            for (Long configId : configIds) {
                BlParkConfig cfg = parkConfigMapper.selectBlParkConfigByConfigId(configId);
                if (cfg != null) configs.add(cfg);
            }
            vo.setHardwareConfig(configs);
        }

        List<Long> serviceIds = blParkMapper.selectParkServiceIdsByParkId(blPark.getParkId());
        if (serviceIds != null && !serviceIds.isEmpty()) {
            List<BlParkService> services = new ArrayList<>();
            for (Long sid : serviceIds) {
                BlParkService svc = parkServiceMapper.selectBlParkServiceByServiceId(sid);
                if (svc != null) services.add(svc);
            }
            vo.setParkServices(services);
        }

        // 仓库类型：优先从JSON字段转换（若存在）
        if (blPark.getWarehouseTypesJson() != null && !blPark.getWarehouseTypesJson().isEmpty()) {
            vo.setWarehouseTypes(convertWarehouseTypes(blPark.getWarehouseTypesJson()));
        } else if (blPark.getWarehouseTypes() != null && !blPark.getWarehouseTypes().isEmpty()) {
            // 如果JSON字段为空，但实体对象中有数据，直接使用
            vo.setWarehouseTypes(blPark.getWarehouseTypes());
        }
        
        // 计算可用面积和出租率
        calculateAreaAndRate(vo);
        
        return vo;
    }
    
    /**
     * 将BlPark列表转换为BlParkVo列表
     * 
     * @param blParkList 园区实体列表
     * @return 园区VO列表
     */
    public List<BlParkVo> convertToVoList(List<BlPark> blParkList) {
        if (blParkList == null || blParkList.isEmpty()) {
            return new ArrayList<>();
        }
        
        return blParkList.stream()
            .map(this::convertToVo)
            .collect(Collectors.toList());
    }

    /**
     * 转换仓库类型JSON为对象列表
     * 
     * @param warehouseTypesJson 仓库类型JSON字符串
     * @return 仓库类型对象列表
     */
    /**
     * 转换仓库类型JSON为对象列表
     * 
     * @param warehouseTypesJson 仓库类型JSON字符串
     * @return 仓库类型对象列表
     */
    private List<BlWarehouseType> convertWarehouseTypes(String warehouseTypesJson) {
        List<Long> typeIds = JsonObjectArrayParser.parseToIdList(warehouseTypesJson);
        if (typeIds == null || typeIds.isEmpty()) {
            return new ArrayList<>();
        }
        
        List<BlWarehouseType> types = new ArrayList<>();
        for (Long typeId : typeIds) {
            try {
                BlWarehouseType type = warehouseTypeMapper.selectBlWarehouseTypeByTypeId(typeId);
                if (type != null) {
                    types.add(type);
                }
            } catch (Exception e) {
                log.warn("Failed to fetch warehouse type with id: {}", typeId, e);
            }
        }
        return types;
    }
    /**
     * 转换硬件配置JSON为对象列表
     * 
     * @param “” 硬件配置JSON字符串
     * @return 硬件配置对象列表
    private List<BlParkConfig> convertHardwareConfig(String hardwareConfigJson) {
        List<Long> configIds = parseJsonToIdList(hardwareConfigJson);
        if (configIds == null || configIds.isEmpty()) {
            return new ArrayList<>();
        }
        
        List<BlParkConfig> configs = new ArrayList<>();
        for (Long configId : configIds) {
            try {
                BlParkConfig config = parkConfigMapper.selectBlParkConfigByConfigId(configId);
                if (config != null) {
                    configs.add(config);
                }
            } catch (Exception e) {
                log.warn("Failed to fetch park config with id: {}", configId, e);
            }
        }
        return configs;
    }
    
    /**
     * 转换园区服务JSON为对象列表
     * 
     * @param parkServicesJson 园区服务JSON字符串
     * @return 园区服务对象列表
     */
    private List<BlParkService> convertParkServices(String parkServicesJson) {
        List<Long> serviceIds = parseJsonToIdList(parkServicesJson);
        if (serviceIds == null || serviceIds.isEmpty()) {
            return new ArrayList<>();
        }
        
        List<BlParkService> services = new ArrayList<>();
        for (Long serviceId : serviceIds) {
            try {
                BlParkService service = parkServiceMapper.selectBlParkServiceByServiceId(serviceId);
                if (service != null) {
                    services.add(service);
                }
            } catch (Exception e) {
                log.warn("Failed to fetch park service with id: {}", serviceId, e);
            }
        }
        return services;
    }
    
    /**
     * 解析JSON字符串为ID列表
     * 
     * @param jsonString JSON字符串
     * @return ID列表
     */
    private List<Long> parseJsonToIdList(String jsonString) {
        if (jsonString == null || jsonString.trim().isEmpty()) {
        }
        
        try {
            return objectMapper.readValue(jsonString, new TypeReference<List<Long>>() {});
        } catch (Exception e) {
            log.warn("Failed to parse JSON string to ID list: {}", jsonString, e);
            return new ArrayList<>();
        }
    }
    
    /**
     * 计算可用面积和出租率
     * 
     * @param vo 园区VO
     */
    private void calculateAreaAndRate(BlParkVo vo) {
        if (vo.getTotalArea() != null && vo.getRentedArea() != null) {
            // 计算可用面积
            vo.setAvailableArea(vo.getTotalArea().subtract(vo.getRentedArea()));
            
            // 计算出租率
            if (vo.getTotalArea().compareTo(BigDecimal.ZERO) > 0) {
                vo.setRentalRate(vo.getRentedArea()
                    .multiply(new BigDecimal("100"))
                    .divide(vo.getTotalArea(), 2, RoundingMode.HALF_UP));
            }
        }
    }

    /**
     * 轻量级转换：将BlPark转换为BlParkVo（不包含关联查询）
     * 专用于分页查询，避免额外的数据库查询干扰分页信息
     * 
     * @param blPark 园区实体
     * @return 园区VO
     */
    public BlParkVo convertToVoLightweight(BlPark blPark) {
        if (blPark == null) {
            return null;
        }
        
        BlParkVo vo = new BlParkVo();
        
        // 复制基本属性
        vo.setParkId(blPark.getParkId());
        vo.setParkName(blPark.getParkName());
        vo.setParkDescription(blPark.getParkDescription());
        vo.setTotalArea(blPark.getTotalArea());
        vo.setBuildingArea(blPark.getBuildingArea());
        vo.setFloorHeight(blPark.getFloorHeight());
        vo.setLocation(blPark.getLocation());
        vo.setLongitude(blPark.getLongitude());
        vo.setLatitude(blPark.getLatitude());
        vo.setRentedArea(blPark.getRentedArea());
        vo.setRentalPrice(blPark.getRentalPrice());
        vo.setManager(blPark.getManager());
        vo.setContactPhone(blPark.getContactPhone());
        vo.setThumbnailUrl(blPark.getThumbnailUrl());
        vo.setPosterUrl(blPark.getPosterUrl());
        vo.setIsRecommend(blPark.getIsRecommend());
        vo.setCreateTime(blPark.getCreateTime());
        vo.setUpdateTime(blPark.getUpdateTime());
        vo.setAreaId(blPark.getAreaId());
        vo.setContactAddress(blPark.getContactAddress());
        vo.setContactEmail(blPark.getContactEmail());
        vo.setBannerPage(blPark.getBannerPage());
        vo.setFireLevel(blPark.getFireLevel());
        
        // 初始化列表为空，避免前端看到null
        vo.setParkTags(new ArrayList<>());
        vo.setWarehouseTypes(new ArrayList<>());
        vo.setHardwareConfig(new ArrayList<>());
        vo.setParkServices(new ArrayList<>());
        
        // 计算可用面积和出租率
        calculateAreaAndRate(vo);
        
        return vo;
    }

    /**
     * 轻量级转换：将BlPark列表转换为BlParkVo列表（不包含关联查询）
     * 专用于分页查询，避免额外的数据库查询干扰分页信息
     * 
     * @param blParkList 园区实体列表
     * @return 园区VO列表
     */
    public List<BlParkVo> convertToVoListLightweight(List<BlPark> blParkList) {
        if (blParkList == null || blParkList.isEmpty()) {
            return new ArrayList<>();
        }
        
        return blParkList.stream()
            .map(this::convertToVoLightweight)
            .collect(Collectors.toList());
    }
}
